package io.finer.erp.jeecg.bas.service.impl;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.oConvertUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.api.client.util.Maps;
import com.google.common.collect.Lists;

import cn.hutool.core.collection.CollUtil;
import io.finer.erp.jeecg.bas.dto.ZrkOrderProductDTO;
import io.finer.erp.jeecg.bas.entity.BasMaterialCategory;
import io.finer.erp.jeecg.bas.entity.SalesDelivery;
import io.finer.erp.jeecg.bas.entity.SalesDeliveryEntry;
import io.finer.erp.jeecg.bas.entity.ZrkOrderDeliveryEntryLk;
import io.finer.erp.jeecg.bas.entity.ZrkOrderProduct;
import io.finer.erp.jeecg.bas.entity.ZrkShoporder;
import io.finer.erp.jeecg.bas.entity.ZzShoporder;
import io.finer.erp.jeecg.bas.mapper.ZrkOrderProductMapper;
import io.finer.erp.jeecg.bas.service.IBasMaterialCategoryService;
import io.finer.erp.jeecg.bas.service.ISalesDeliveryEntryService;
import io.finer.erp.jeecg.bas.service.ISalesDeliveryService;
import io.finer.erp.jeecg.bas.service.IZrkOrderDeliveryEntryLkService;
import io.finer.erp.jeecg.bas.service.IZrkOrderProductService;
import io.finer.erp.jeecg.bas.service.IZrkShoporderService;
import io.finer.erp.jeecg.bas.service.IZzShoporderService;
import io.finer.erp.jeecg.bas.vo.OrderProductVO;
import io.finer.erp.jeecg.finance.entity.FinaReceiptEntryLk;
import io.finer.erp.jeecg.finance.service.IFinaReceiptEntryLkService;

/**
 * @Description: 商城订单产品明细表
 * @Author: jeecg-boot
 * @Date:   2020-08-22
 * @Version: V1.0
 */
@Service
public class ZrkOrderProductServiceImpl extends ServiceImpl<ZrkOrderProductMapper, ZrkOrderProduct> implements IZrkOrderProductService {
	
	@Autowired
	private ZrkOrderProductMapper zrkOrderProductMapper;
	@Autowired
	private IZrkShoporderService shoporderService;
	@Autowired
	private IBasMaterialCategoryService categoryService;
	@Autowired
	private IZzShoporderService zzShoporderService;
	@Autowired
	private IZrkOrderDeliveryEntryLkService deliverLkService;
	@Autowired
	private ISalesDeliveryEntryService deliveryEntryService;
	@Autowired
	private ISalesDeliveryService deliveryService;
	@Autowired
	private IFinaReceiptEntryLkService entryLkService;
	
	@Override
	public List<ZrkOrderProduct> selectByMainId(String mainId) {
		return zrkOrderProductMapper.selectByMainId(mainId);
	}

	@Override
	public ZrkOrderProduct getLatestByCustom(String customId, String categoryId) {
		LambdaQueryWrapper<ZrkShoporder> orderQuery = new LambdaQueryWrapper<>();
		orderQuery.eq(ZrkShoporder::getCustomerId, customId);
		orderQuery.orderByDesc(ZrkShoporder::getCreateTime);
		List<ZrkShoporder> orders = this.shoporderService.list(orderQuery);
		if(null == orders || 0 == orders.size()) {
			return null;
		}
		List<String> orderIdList = Lists.newArrayList();
		for (ZrkShoporder order : orders) {
			orderIdList.add(order.getId());
		}
		LambdaQueryWrapper<ZrkOrderProduct> productQuery = new LambdaQueryWrapper<>();
		productQuery.in(ZrkOrderProduct::getOrderId, orderIdList);
		productQuery.eq(ZrkOrderProduct::getMaterialId, categoryId);
		productQuery.orderByDesc(ZrkOrderProduct::getCreateTime);
		List<ZrkOrderProduct> list = list(productQuery);
		if(null != list && list.size() > 0) {
			return list.get(0);
		}
		return null;
	}

	@Override
	public Result<?> getChild(String id) {
		List<ZrkOrderProductDTO> list = this.baseMapper.selectChildByMainId(id);
		return Result.ok(list);
	}
	
	@Override
	public Result<?> addOrderProduct(OrderProductVO orderProductVO) {
		if(StringUtils.isBlank(orderProductVO.getOrderId())) {
			return Result.error("未选中销售订单");
		}
		ZrkOrderProduct orderProduct = new ZrkOrderProduct();
		if(oConvertUtils.isNotEmpty(orderProductVO.getId())) {
			orderProduct = this.getById(orderProductVO.getId());
		}
		orderProduct.setQzTotal(orderProductVO.getQzTotal());//切张总价
		String categoryId = orderProductVO.getMaterialId();
		if(oConvertUtils.isEmpty(orderProductVO.getMaterialId())) {
			categoryId = orderProductVO.getName();
		}
		orderProduct.setMaterialId(categoryId);
		orderProduct.setUnitPrice(orderProductVO.getPrice());
		orderProduct.setProductCount(orderProductVO.getNumber());
		orderProduct.setJsId(orderProductVO.getJsId());
		orderProduct.setRemark(orderProductVO.getRemark());
		orderProduct.setProductType(orderProductVO.getProductType());
		orderProduct.setFormularId(orderProductVO.getFormular());
		orderProduct.setProductSpecs(orderProductVO.getModal());
		orderProduct.setProduceInfo(orderProductVO.getModal());
		orderProduct.setProcessId(orderProductVO.getProcessId());
		orderProduct.setProType(orderProductVO.getProType());
		orderProduct.setOrderFit(1);
		
		ZrkShoporder zrkShoporder = shoporderService.getById(orderProductVO.getOrderId());
		if(zrkShoporder==null) {
			return Result.error("未找到销售订单");
		}
		if(StringUtils.equals(zrkShoporder.getDelFlag(), "1")) {
			return Result.error("不可操作产品明细，该订单已作废");
		}
		return this.saveOrder(orderProductVO,zrkShoporder, orderProduct);
	}
	
	private boolean isNumber(String number) {
		int index = number.indexOf(".");
		if (index < 0) {
			return StringUtils.isNumeric(number);
		} else {
			String num1 = number.substring(0, index);
			String num2 = number.substring(index + 1);

			return StringUtils.isNumeric(num1) && StringUtils.isNumeric(num2);
		}
	}
	
	private Result<?> saveOrder(OrderProductVO orderProductVO,ZrkShoporder zrkShoporder, ZrkOrderProduct orderProduct){
		List<ZzShoporder> shoporderList = zzShoporderService.selectOrderByOrderNo(zrkShoporder.getOrderNo());
		if(shoporderList!=null&&shoporderList.size()>0) {
			for(ZzShoporder zzShopoder:shoporderList) {
				if(zzShopoder.getWoStatus()>1&&zzShopoder.getWoStatus()!=5) {
					return Result.error("订单已接单，不可修改");
				}
			}
		}
		if(StringUtils.isBlank(orderProduct.getId())) {
			orderProduct.setCreateTime(DateUtils.getDate());
			this.saveMain(orderProductVO,zrkShoporder, orderProduct);
			return Result.ok("保存成功。");
		} else {
			this.updateMain(orderProductVO,zrkShoporder, orderProduct);
			return Result.ok("修改成功。");
		}
	}
	
	@Transactional
	public void saveMain(OrderProductVO orderProductVO,ZrkShoporder zrkShoporder,ZrkOrderProduct orderProduct) {
		//外键设置
		orderProduct.setOrderNo(zrkShoporder.getShopOrder());
		orderProduct.setOrderId(zrkShoporder.getId());
		String categoryId = orderProduct.getMaterialId();
		BasMaterialCategory category = categoryService.getById(categoryId);
		orderProduct.setProductName(category.getName());
		orderProduct.setUnitId(category.getUnitId());
		BigDecimal totalPrice = zrkShoporder.getOrderMoney();
		if(orderProduct!=null) {
			BigDecimal unitPrice = orderProduct.getUnitPrice()==null?BigDecimal.ZERO:orderProduct.getUnitPrice();
			BigDecimal number = orderProduct.getProductCount()==null?BigDecimal.ZERO:orderProduct.getProductCount();
			String modal = orderProduct.getProductSpecs();
			if(StringUtils.isNotBlank(modal)) {
				BigDecimal orderProductPrice = null;
				String[] strs = StringUtils.split(modal, "*");
				boolean flag = false;
				if(strs.length==1) {
					flag = true;
				} else {
					String str1 = strs[0];
					String str2 = strs[1];
					boolean isNumberFlag = false;
					if(isNumber(str1) && isNumber(str2)) {
						isNumberFlag = true;
					}
					if(isNumberFlag && null != unitPrice) {
						BigDecimal num1 = new BigDecimal(str1);
						BigDecimal num2 = new BigDecimal(str2);
						BigDecimal big = new BigDecimal("0");
						if(num1.compareTo(big) > 0 || num2.compareTo(big) > 0) {
							BigDecimal w = num1.divide(new BigDecimal("100"), 4, BigDecimal.ROUND_DOWN);
							orderProductPrice = w.multiply(num2).multiply(number).multiply(unitPrice);
						} else {
							BigDecimal w = num1.divide(new BigDecimal("100"), 4, BigDecimal.ROUND_DOWN);
							BigDecimal l = num2.divide(new BigDecimal("100"), 4, BigDecimal.ROUND_DOWN);
							orderProductPrice = w.multiply(l).multiply(number).multiply(unitPrice);
						}
					} else {
						flag = true;
					}
				}
				if(flag && null != unitPrice) {
					orderProductPrice = unitPrice.multiply(number);
				}
				if(oConvertUtils.isNotEmpty(orderProductPrice)) {
					orderProductPrice.setScale(2, BigDecimal.ROUND_DOWN);
					orderProduct.setTotalPrice(orderProductPrice);
					if("1".equals(orderProduct.getProductType())){
						totalPrice = totalPrice.add(orderProductPrice);
					}
				}
			}
		}
		zrkOrderProductMapper.insert(orderProduct);
		totalPrice = totalPrice.setScale(2, BigDecimal.ROUND_DOWN);
		zrkShoporder.setOrderMoney(totalPrice);
		shoporderService.updateById(zrkShoporder);
	}
	
	@Transactional
	public void updateMain(OrderProductVO orderProductVO,ZrkShoporder zrkShoporder,ZrkOrderProduct orderProduct) {
		//外键设置
		orderProduct.setOrderNo(zrkShoporder.getShopOrder());
		orderProduct.setOrderId(zrkShoporder.getId());
		String categoryId = orderProduct.getMaterialId();
		BasMaterialCategory category = categoryService.getById(categoryId);
		orderProduct.setProductName(category.getName());
		orderProduct.setUnitId(category.getUnitId());
		BigDecimal totalPrice = zrkShoporder.getOrderMoney();
		if(orderProduct!=null) {
			BigDecimal unitPrice = orderProduct.getUnitPrice()==null?BigDecimal.ZERO:orderProduct.getUnitPrice();
			BigDecimal number = orderProduct.getProductCount()==null?BigDecimal.ZERO:orderProduct.getProductCount();
			String modal = orderProduct.getProductSpecs();
			if(StringUtils.isNotBlank(modal)) {
				BigDecimal orderProductPrice = null;
				String[] strs = StringUtils.split(modal, "*");
				boolean flag = false;
				if(strs.length==1) {
					flag = true;
				} else {
					String str1 = strs[0];
					String str2 = strs[1];
					boolean isNumberFlag = false;
					if(isNumber(str1) && isNumber(str2)) {
						isNumberFlag = true;
					}
					if(isNumberFlag && null != unitPrice) {
						BigDecimal num1 = new BigDecimal(str1);
						BigDecimal num2 = new BigDecimal(str2);
						BigDecimal big = new BigDecimal("0");
						if(num1.compareTo(big) > 0 || num2.compareTo(big) > 0) {
							BigDecimal w = num1.divide(new BigDecimal("100"), 4, BigDecimal.ROUND_DOWN);
							orderProductPrice = w.multiply(num2).multiply(number).multiply(unitPrice);
						} else {
							BigDecimal w = num1.divide(new BigDecimal("100"), 4, BigDecimal.ROUND_DOWN);
							BigDecimal l = num2.divide(new BigDecimal("100"), 4, BigDecimal.ROUND_DOWN);
							orderProductPrice = w.multiply(l).multiply(number).multiply(unitPrice);
						}
					} else {
						flag = true;
					}
				}
				if(flag && null != unitPrice) {
					orderProductPrice = unitPrice.multiply(number);
				}
				ZrkOrderProduct order = this.getById(orderProductVO.getId());
				if(null != orderProductPrice) {
					orderProductPrice.setScale(2, BigDecimal.ROUND_DOWN);
					if("1".equals(orderProduct.getProductType())){
						totalPrice = totalPrice.add(orderProductPrice).subtract(orderProduct.getTotalPrice());
					}
					orderProduct.setTotalPrice(orderProductPrice);
				}
			}
		}
		zrkOrderProductMapper.updateById(orderProduct);
		totalPrice = totalPrice.setScale(2, BigDecimal.ROUND_DOWN);
		zrkShoporder.setOrderMoney(totalPrice);
		shoporderService.updateById(zrkShoporder);
	}

	@Override
	@Transactional
	public Result<?> deleteOrderProduct(String id) {
		ZrkOrderProduct orderProduct = baseMapper.selectById(id);
		if(orderProduct==null) {
			return Result.error("未找到该订单产品明细");
		}
		if(oConvertUtils.isEmpty(orderProduct.getOrderId())) {
			return Result.error("未找到该订单产品明细对应的销售订单");
		}
		ZrkShoporder zrkShoporder = shoporderService.getById(orderProduct.getOrderId());
		if(zrkShoporder==null) {
			return Result.error("未找到销售订单");
		}
		if(StringUtils.equals(zrkShoporder.getDelFlag(), "1")) {
			return Result.error("不可删除该产品明细，该订单已作废");
		}
		List<ZzShoporder> shoporderList = zzShoporderService.selectOrderByOrderNo(zrkShoporder.getOrderNo());
		if(shoporderList!=null&&shoporderList.size()>0) {
			for(ZzShoporder zzShopoder:shoporderList) {
				if(zzShopoder.getWoStatus()>1&&zzShopoder.getWoStatus()!=5) {
					return Result.error("订单已接单，不可修改");
				}
			}
		}
		BigDecimal totalPrice = zrkShoporder.getOrderMoney();
		BigDecimal orderProductPrice = BigDecimal.ZERO;
		if(oConvertUtils.isNotEmpty(orderProduct.getTotalPrice())) {
			orderProductPrice = orderProduct.getTotalPrice();
		}
		if("1".equals(orderProduct.getProductType())){
			totalPrice = totalPrice.subtract(orderProductPrice);
		}
		zrkShoporder.setOrderMoney(totalPrice);
		int i = baseMapper.deleteById(id);
		if(i==0) {
			return Result.error("删除失败");
		}
		shoporderService.updateById(zrkShoporder);
		return Result.ok("删除成功");
	}

	@Override
	@Transactional
	public boolean changePrice(ZrkOrderProduct orderProductVO) {
		// TODO Auto-generated method stub
		ZrkOrderProduct orderProduct = baseMapper.selectById(orderProductVO.getId());
		if(orderProduct==null) {
			throw new RuntimeException("未找到该订单产品明细");
		}
		if(orderProductVO.getUnitPrice()==null) {
			throw new RuntimeException("未找到该订单产品明细");
		}
		ZrkShoporder zrkShoporder = shoporderService.getById(orderProductVO.getId());
		if(zrkShoporder==null) {
			throw new RuntimeException("未找到销售订单");
		}
		if(StringUtils.equals(zrkShoporder.getDelFlag(), "1")) {
			throw new RuntimeException("不可修改单价，该订单已作废");
		}
		if(StringUtils.equals("false", orderProductVO.getIsSynchronized())) {
			orderProduct.setUnitPrice(orderProductVO.getUnitPrice());
			return this.updateById(orderProduct);
		}
		LambdaQueryWrapper<ZrkOrderDeliveryEntryLk> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(ZrkOrderDeliveryEntryLk::getOrderId, orderProductVO.getId());
		List<ZrkOrderDeliveryEntryLk> lkList = deliverLkService.list(queryWrapper);
		orderProduct.setUnitPrice(orderProductVO.getUnitPrice());
		this.updateById(orderProduct);
		if(CollUtil.isEmpty(lkList)) {
			return true;
		}else {
			//临时存放发货单详情id，查询是否有发货单数据
			List<String> deliverIdList = Lists.newArrayList();
			Map<String, List<ZrkOrderDeliveryEntryLk>> materialMap = Maps.newHashMap();
			for(ZrkOrderDeliveryEntryLk lk:lkList) {
				if(!CollUtil.contains(deliverIdList, lk.getDeliveryEntryId())) {
					List<ZrkOrderDeliveryEntryLk> materialIdList = Lists.newArrayList();
					materialIdList.add(lk);
					materialMap.put(lk.getDeliveryEntryId(), materialIdList);
					deliverIdList.add(lk.getDeliveryEntryId());
				}else {
					if(StringUtils.isNotBlank(lk.getDeliveryEntryId())
							&& StringUtils.isNotBlank(lk.getMaterialId())) {
						materialMap.get(lk.getDeliveryEntryId()).add(lk);
					}
				}
				
			}
			//判断四否存在发货单，若不存在，直接修改销售订单单价
			if(CollUtil.isEmpty(deliverIdList)) {
				return true;
			}else {
				List<SalesDeliveryEntry> deliveryEntryList = deliveryEntryService.listByIds(deliverIdList);
				if(deliveryEntryList!=null && deliveryEntryList.size()>0) {
					for(SalesDeliveryEntry entry:deliveryEntryList) {
						List<ZrkOrderDeliveryEntryLk> entryLkList = materialMap.get(entry.getId());
						if(CollUtil.isNotEmpty(entryLkList)) {
							BigDecimal priceSum = BigDecimal.ZERO;//每条发货单明细对应的发货总价与修改单价后总价的差值
							for(ZrkOrderDeliveryEntryLk entryLk:entryLkList) {
								priceSum = priceSum.add(orderProductVO.getUnitPrice()
										.subtract(entryLk.getUnitPrice()).multiply(entryLk.getQty()));
								entryLk.setUnitPrice(orderProductVO.getUnitPrice());
							}
							deliverLkService.updateBatchById(entryLkList);
							entry.setTotalPrice(entry.getTotalPrice().add(priceSum));
							BigDecimal hxPrice = BigDecimal.ZERO;
							if(entry.getWriteAmount()!=null) {
								hxPrice = entry.getWriteAmount();
							}
							if(entry.getTotalPrice().compareTo(hxPrice)<=0) {
								entry.setWriteStatus("2");
							}else if(entry.getTotalPrice().compareTo(hxPrice)>0 && hxPrice.compareTo(BigDecimal.ZERO)!=0) {
								entry.setWriteStatus("1");
							}else {
								entry.setWriteStatus("0");
							}
							SalesDelivery salesDelivery = deliveryService.getById(entry.getDeliveryId());
							salesDelivery.setTotalAmount(salesDelivery.getTotalAmount().add(priceSum));
							if(salesDelivery.getTotalAmount()!=null) {
								salesDelivery.setTotalBig(ZrkDeliverEntryServiceImpl.toChinese(salesDelivery.getTotalAmount().toString()));
							}
							deliveryService.updateById(salesDelivery);
							LambdaQueryWrapper<FinaReceiptEntryLk> query = new LambdaQueryWrapper<>();
							query.eq(FinaReceiptEntryLk::getEntryId, entry.getId());
							query.orderByDesc(FinaReceiptEntryLk::getCreateTime);
							List<FinaReceiptEntryLk> receiptEntryLkList = entryLkService.list(query);
							FinaReceiptEntryLk receiptEntryLk = null;
							if(CollUtil.isNotEmpty(receiptEntryLkList)) {
								receiptEntryLk = receiptEntryLkList.get(0);
								if(entry.getTotalPrice().compareTo(hxPrice)<=0) {
									receiptEntryLk.setEntryStatus("2");
								}else if(entry.getTotalPrice().compareTo(hxPrice)>0 && hxPrice.compareTo(BigDecimal.ZERO)!=0) {
									receiptEntryLk.setEntryStatus("1");
								}else {
									receiptEntryLk.setEntryStatus("0");
								}
							}
						}
					}
					return deliveryEntryService.updateBatchById(deliveryEntryList);
				}
			}
		}
		return false;
	}

	@Override
	public List<ZrkOrderProduct> getByCustomerId(String customerId) {
		return this.baseMapper.getByCustomerId(customerId);
	}
	
	@Override
	public List<ZrkOrderProduct> getByCustomerId2(String customerId) {
		return this.baseMapper.getByCustomerId2(customerId);
	}

	@Override
	public List<ZrkOrderProduct> getCustomerNotOutCompleteProduct(String customerId) {
		// TODO Auto-generated method stub
		return this.baseMapper.getCustomerNotOutCompleteProduct(customerId);
	}
}
